﻿using System;
using System.Runtime.CompilerServices;
using Microsoft.CSharp.RuntimeBinder;

namespace NoMvvm
{
    internal static class DynamicUtility
    {
        private static readonly DynamicCache _cache = new DynamicCache();

        public static object GetDynamicMember(object obj, string memberName)
        {
            Type type = obj.GetType();
            CallSite<Func<CallSite, object, object>> callsite;
            if (!_cache.TryGet(type, memberName, out callsite))
            {
                var binder = Binder.GetMember(CSharpBinderFlags.None, memberName, type, new[] 
                { 
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) 
                });
                callsite = CallSite<Func<CallSite, object, object>>.Create(binder);
                _cache.Add(type, memberName, callsite);
            }
            return callsite.Target(callsite, obj);
        }
    }
}
